﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using DeutscheRemoval.Utils;
using Agos.Utils;
using System.Configuration;

namespace DeutscheRemoval
{
    class Automation
    {
        string searchPath1 = ConfigurationManager.AppSettings["FirstSearchPath"];
        string searchPath2 = ConfigurationManager.AppSettings["SecondSearchPath"];
        string outputFilePath = ConfigurationManager.AppSettings["OutputFilePath"];
        string outputFile = ConfigurationManager.AppSettings["OutputFilename"];

        public Automation()
        {
        }
        /// <summary>
        ///  Receives a dataTable with the excel informations and loops each record
        /// </summary>
        /// <param name="dt">First row in dt.Rows is the header</param>
        public string Start(DataTable dt)
        {
            DataColumn statusColumn = new DataColumn("Status");
            DataColumn destinationPath = new DataColumn("Path");
            DataColumn sourcePath = new DataColumn("SourcePath");
            
            dt.Columns.Add(destinationPath);
            dt.Columns.Add(statusColumn);
            dt.Columns.Add(sourcePath);

            DataColumn dataColumn = dt.Columns["DATA1"]; //pentru construire path catre fisier
            IEnumerable<FileInfo> fileList = null;
            Dictionary<int, List<FileInfo>> filesDict = null;
            bool foundFile = false;

            //INDEXARE ~ 6 min
            //fileList = FileUtils.BuildFileList(searchPath2); //4 minutes for 65000 files :|
            filesDict = BuildDictionary(searchPath2); //time consuming for indexing but O(1) for get :D 

            if (dataColumn != null)
            {
                foreach (DataRow row in dt.Rows)
                {
                    int index = dt.Rows.IndexOf(row);
                    foundFile = false;
                    if (index == 0) //if we are on the first row
                    {
                        row[statusColumn] = "Operation Status";
                        row[sourcePath] = "Path of Source";
                        row[destinationPath] = "Path of Destination";
                        continue;
                    }
                    else
                    {
                        #region SearchFirstPath
                        //very ugly because the filePath can have multiple forms
                        // could use indexing as well for searchpath1
                        string filePath = LookUpFilePath(row["DATA1"].ToString(), row["COD_VEL"].ToString(), searchPath1);//firstPath
                        string filePathh = LookUpFilePath1(row["DATA1"].ToString(), row["COD_VEL"].ToString(), searchPath1);//firstPath
                        string filePathhh = LookUpFilePath2(row["DATA1"].ToString(), row["COD_VEL"].ToString(), searchPath1);//firstPath
                        if ( (filePath != "" && File.Exists(filePath)))
                        {
                            string newFilePath = BuildDestionationPath(outputFilePath, row["DATA1"].ToString(), row["CONTRATTO"].ToString(), row["COD_VEL"].ToString());
                            if (newFilePath != "")
                            {
                                FileUtils.CopyRenamed(filePath, newFilePath);
                                row[statusColumn] = "ok";
                                foundFile = true;
                                row[destinationPath] = newFilePath;
                                row[sourcePath] = filePath;
                                continue;
                            }
                        }
                        if ((filePathh != "" && File.Exists(filePathh)))
                        {
                            string newFilePath = BuildDestionationPath(outputFilePath, row["DATA1"].ToString(), row["CONTRATTO"].ToString(), row["COD_VEL"].ToString());
                            if (newFilePath != "")
                            {
                                FileUtils.CopyRenamed(filePathh, newFilePath);
                                row[statusColumn] = "ok";
                                foundFile = true;
                                row[destinationPath] = newFilePath;
                                row[sourcePath] = filePathh;
                                continue;
                            }
                        }
                        if ((filePathhh != "" && File.Exists(filePathhh)))
                        {
                            string newFilePath = BuildDestionationPath(outputFilePath, row["DATA1"].ToString(), row["CONTRATTO"].ToString(), row["COD_VEL"].ToString());
                            if (newFilePath != "")
                            {
                                FileUtils.CopyRenamed(filePathhh, newFilePath);
                                row[statusColumn] = "ok";
                                foundFile = true;
                                row[destinationPath] = newFilePath;
                                row[sourcePath] = filePathhh;
                                continue;
                            }
                        }
                        #endregion SearchFirstPath
                        else  // SEARCH ROUTINE in 2nd path
                        {
                            #region SearchWithFileList
                            //if (fileList != null)
                            //{
                            //    for (int i = 0; i < fileList.Count(); i += 1)
                            //    {
                            //        FileInfo currentFile = fileList.ElementAt(i);
                            //        try
                            //        {
                            //            //parent directory and also parent of parent
                            //            if (currentFile.Directory.Name.ToString() == row["COD_VEL"].ToString()) //directory name can be bigger than 248
                            //            {
                            //                string newFilePath = BuildDestionationPath(destionationPathRoot, row["DATA1"].ToString(), row["CONTRATTO"].ToString());
                            //                if (newFilePath != "")
                            //                {
                            //                    FileUtils.CopyRenamed(currentFile.Directory.FullName + @"\" + currentFile.Name, newFilePath);
                            //                    row[statusColumn] = "ok";
                            //                    row[filepathColumn] = newFilePath;
                            //                    row[sourcePath] = filePath;
                            //                }
                            //            }
                            //        }
                            //        catch (PathTooLongException exce)
                            //        {
                            //            Debug.WriteLine(fileList.ElementAt(i).Name);
                            //        }
                            //        finally
                            //        {

                            //        }
                            //    }
                            //}
                            //
                            #endregion SearchWithFileList
                            #region SearchWithDictionary
                            if (filesDict != null)
                            {
                                int key = FileUtils.ParseCodVel(row["COD_VEL"].ToString());
                                if (filesDict.ContainsKey(key))
                                {
                                    FileInfo current = null;
                                    try
                                    { 
                                        //parcurge lista de datorii ale debitorului
                                        List<FileInfo> fis = filesDict[key];
                                        foreach (FileInfo item in fis)
                                        {
                                            current = item;
                                            if (CheckDebt(item, row["COD_VEL"].ToString(), row["DATA1"].ToString())) //directory name can be bigger than 248 To do
                                            {
                                                string newFilePath = BuildDestionationPath(outputFilePath, row["DATA1"].ToString(), row["CONTRATTO"].ToString(), row["COD_VEL"].ToString());
                                                if (newFilePath != "")
                                                {
                                                    FileUtils.CopyRenamed(item.Directory.FullName + @"\" + item.Name, newFilePath);
                                                    row[statusColumn] = "ok";
                                                    foundFile = true;
                                                    row[destinationPath] = newFilePath;
                                                    row[sourcePath] = item.Directory.FullName + @"\" + item.Name;
                                                }
                                            }
                                        }
                                    }
                                    catch (PathTooLongException exce)
                                    {
                                        Logger.Log(exce.Message + " " + current.Directory.Name, LogType.File);
                                    }
                                    finally
                                    {

                                    }
                                }
                            }
                            #endregion SearchWithDictionary
                        }
                    }
                    if (foundFile == false)
                    {
                            row[statusColumn] = "not Ok";
                            row[destinationPath] = "File non trovato";
                    }
                }
               // outputFile = FileUtils.AppendDateToFileName(outputFile);
                return ExcelUtils.FastExport(outputFilePath, dt, outputFile);
            }
            return "notok";
        }
        /// <summary>
        /// Build a possible file path and check if it exists
        /// </summary>
        /// <param name="extractedDate"></param>
        /// <param name="codClient"></param>
        /// <param name="rootDir"></param>
        /// <returns></returns>
        public string LookUpFilePath(string extractedDate, string codClient, string rootDir)
        {
            string searchPath = "";
            DateTime date = DateTime.MinValue;
            if (extractedDate != "" && codClient != "")
            {
                date = DateTime.Parse(extractedDate);
                CultureInfo english = new CultureInfo("en-US");
                
                string month = english.DateTimeFormat.GetMonthName(date.Month).ToUpper();
                month = FileUtils.enCultureToItalian(month);
                //parse month
                string day = date.Day.ToString();
                string year = date.Year.ToString();
                string folderDate = date.ToString("dd'.'MM'.'yyyy ");
                
                //make a check to see if rootDir lastC
                searchPath += rootDir + year + @"\" + month + " " + year + @"\" + folderDate + @"\" + codClient + ".pdf";
            }
            return searchPath;
        }

        public string LookUpFilePath1(string extractedDate, string codClient, string rootDir)
        {
            string searchPath = "";
            DateTime date = DateTime.MinValue;
            if (extractedDate != "" && codClient != "")
            {
                date = DateTime.Parse(extractedDate);
                CultureInfo english = new CultureInfo("en-US");

                string month = english.DateTimeFormat.GetMonthName(date.Month).ToUpper();
                month = FileUtils.enCultureToItalian(month);
                //parse month
                string day = date.Day.ToString();
                string year = date.Year.ToString();
                string folderDate = date.ToString("dd'_'MM'_'yyyy ");

                //make a check to see if rootDir lastC
                searchPath += rootDir + year + @"\" + month + " " + year + @"\" + folderDate + @"\" + codClient + ".pdf";
            }
            return searchPath;
        }

        public string LookUpFilePath2(string extractedDate, string codClient, string rootDir)
        {
            string searchPath = "";
            DateTime date = DateTime.MinValue;
            if (extractedDate != "" && codClient != "")
            {
                date = DateTime.Parse(extractedDate);
                CultureInfo english = new CultureInfo("en-US");

                string month = english.DateTimeFormat.GetMonthName(date.Month).ToUpper();
                month = FileUtils.enCultureToItalian(month);
                //parse month
                string day = date.Day.ToString();
                string year = date.Year.ToString();
                string folderDate = date.ToString("dd'.'MM'.'yyyy ");

                //make a check to see if rootDir lastC
                searchPath += rootDir + year + @"\" + month + " " + year + @"\" +"ENI "+ folderDate + @"\" + codClient + ".pdf";
            }
            return searchPath;
        }


        public string GetLookUpFilePath(string extractedDate, string codClient, string rootDir)
        {
            string searchPath = "";
            string[] foundFiles = null;
            DateTime date = DateTime.MinValue;
            if (extractedDate != "" && codClient != "")
            {
                date = DateTime.Parse(extractedDate);
                string month = CultureInfo.CurrentCulture.DateTimeFormat.GetMonthName(date.Month).ToUpper();
                string day = date.Day.ToString();
                string year = date.Year.ToString();
                string folderDate = date.ToString("dd'.'MM'.'yyyy ");

                int number = Directory.GetFiles(rootDir, "*", SearchOption.AllDirectories).Length;

                searchPath += rootDir  + year + @"\" + month + " " + year + @"\" + folderDate + @"\" + codClient + ".pdf";
            }
            return searchPath;
        }

        public string BuildDestionationPath(string destinationPathRoot, string extractedDate, string contratto, string cod_vel)
        {
            string newPath = "";
            if (extractedDate != "" && contratto != "")
            {
                DateTime date = DateTime.Parse(extractedDate);
                CultureInfo english = new CultureInfo("en-US");
                string month = english.DateTimeFormat.GetMonthName(date.Month).ToUpper();
                month = FileUtils.enCultureToItalian(month);
                string day = date.Day.ToString();
                string year = date.Year.ToString();
                string folderDate = date.ToString("dd'.'MM'.'yyyy");
                newPath += destinationPathRoot + year + @"\" + month + " " + year + @"\" + folderDate + @"\" + cod_vel + @"\" + contratto + ".pdf";
            }
            return newPath;
        }

        public Dictionary<int, List<FileInfo>> BuildDictionary(string searchPathh)
        {
            string testSearchPath = searchPathh;
            Dictionary<int, List<FileInfo>> dict = new Dictionary<int, List<FileInfo>>();
            dict = FileUtils.GetFilesDictionary(FileUtils.BuildFileList(new DirectoryInfo(testSearchPath)));

            return dict;
        }

        bool CheckDebt(FileInfo debt, string cod_vel, string data)
        {
           //directorul parinte este codVel
            if (FileUtils.ParseCodVel(debt.Directory.Name).ToString() == cod_vel )  
                if ( debt.Directory.Parent.Name.ToString() == FolderDateFormat(data)) //and parent is date
                return true;
            return false;
        }

        string FolderDateFormat(string input_file_date)
        {
            DateTime date = DateTime.MinValue;
            if (input_file_date != "")
            {
                date = DateTime.Parse(input_file_date);
                string month = CultureInfo.CurrentCulture.DateTimeFormat.GetMonthName(date.Month).ToUpper();
                string day = date.Day.ToString();
                string year = date.Year.ToString();
                string folderDate = date.ToString("dd'.'MM'.'yyyy");
                return folderDate;
            }
            return "";
        }

       
    }
}
